Skip to content

Replication Crashes on iPad with 500 MB Data: OPFS JSON Parse Error After Crash (RxDB 16.9.0) #7074

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
morfees opened this issue Apr 10, 2025 · 17 comments

Comments

@morfees
Copy link

morfees commented Apr 10, 2025

I’m encountering an issue when replicating a large dataset (approximately 500 MB) on an iPad. During replication, the device’s memory eventually becomes saturated, and the app crashes and restarts. After restarting, replication does not resume properly; instead, I receive the following error:

Image

Steps to Reproduce:
1. Replicate a collection of roughly 500 MB on an iPad (about 1 Gb with all the collections combined).
2. Allow replication to run until the iPad memory is saturated.
3. Once the memory is exhausted, the app crashes and restarts.
4. On restart, replication does not resume, and instead, the worker displays the error mentioned above.

Hypothesis:
My suspicion is that due to the crash, the app did not manage to complete writing all the data into the OPFS storage. As a result, only part of the data gets stored, leading to a corrupted JSON file (with, for example, a missing closing bracket). When the replication resumes and attempts to read from this file, it runs into a parsing error because of the corrupted data.

Questions / Requests for Assistance:
1. Is it possible that an unexpected crash during replication would leave the OPFS storage in a corrupted state?
3. Are there recommended practices or changes in RxDB that could help prevent this issue?
4• Is there a way to safely reset the database or detect/recover from such a corruption when an app crash occurs?
5• Any suggestions on handling large replication tasks on resource-constrained environments like an iPad to avoid such crashes?

Additional Notes:
• Since I cannot directly access the OPFS storage on the iPad to inspect the file contents, any guidance on remote debugging or logging would be helpful.

•	"rxdb": "16.9.0"
•	"rxdb-premium": "16.9.0"
•	Platform: iPad (using OPFS for storage)

I appreciate any help or suggestions on how to resolve this issue. Thank you!

@pubkey
Copy link
Owner

pubkey commented Apr 11, 2025

We write JSON of documents in blocks in a way where either the full json is stored or nothing.
From my side this looks like a safari bug (still has to be fixed on the RxDB side).
Do you think you can try to reproduce the problem im chrom on a desktop device?

@morfees
Copy link
Author

morfees commented Apr 11, 2025

It was just a hypothesis, so I’m not entirely sure.
As for reproducing the issue on Chrome for desktop, I haven’t been able to, my computer has significantly more RAM. The problem seems to occur specifically for users on iPads with 3 to 4 GB of RAM. It performs noticeably better on iPads with 6 GB of RAM.

@pubkey
Copy link
Owner

pubkey commented Apr 11, 2025

Its possible to simulate less ram by running the browser in a docker container where you can define how much ram can be used.

@morfees
Copy link
Author

morfees commented Apr 18, 2025

@pubkey I was able to reproduce it on a chromium browser on ubuntu :

Image

I also have this error sometimes :

Image

Since swapping indexDB with OPFS (+sharding), the app has been unpredictable on the ipad, we didn't have these errors with indexDB, but we had to switch because indexDB couldn't handle the size of the data we replicate.

@morfees
Copy link
Author

morfees commented Apr 18, 2025

I also feel like the app is using a lot more RAM with OPFS than with indexDB

@morfees
Copy link
Author

morfees commented Apr 18, 2025

@pubkey I was able to reproduce it on a chromium browser on ubuntu :

Image

I also have this error sometimes :

Image

Since swapping indexDB with OPFS (+sharding), the app has been unpredictable on the ipad, we didn't have these errors with indexDB, but we had to switch because indexDB couldn't handle the size of the data we replicate.

For context and after more testing, I get the error in the second screenshot first and after reloading the page I get the error in the first screenshot.

@morfees
Copy link
Author

morfees commented Apr 18, 2025

I also feel like the app is using a lot more RAM with OPFS than with indexDB

with the OPFS storage, the is a memory leak somewhere, with IndexDB storage our app rarely goes above 1GB of ram for some users, but with OPFS storage like in this example it went above 9GB, we had to restart the app.

Image

@pubkey
Copy link
Owner

pubkey commented Apr 19, 2025

does a restart fix the memory and it goes back to normal? Or will it start up again with the same amount of memory usage?
OPFS stores the index-string-to-document-position-mapping in memory, this is intentional but it should not raise to 9gb with any sane amount of data.

Do you have any indication if the memory goes up either on reads or on writes?

@morfees
Copy link
Author

morfees commented Apr 19, 2025

does a restart fix the memory and it goes back to normal? Or will it start up again with the same amount of memory usage?

For context the screenshot was taken using dev mode, not on users' devices, but even on the ipad we are seeing some app crashes due to high memory usage, so it restart until it saturated again. I will share our experience below.

Do you have any indication if the memory goes up either on reads or on writes?

Aside from the initial replication where most of the writing happens, our app is mostly read-heavy with some minimal writings for time to time.

Just to share the broader experience for context of the users of our PWA in prod:
• The original reason we switched to OPFS was because some iPad users couldn’t use the app at all with IndexedDB, they had large profiles (~300–500MB in one collection), and Safari’s storage limits were preventing replication.
• Those users were falling back to using desktop browsers (Chrome, Edge), but we wanted to support them properly on iPad, so OPFS seemed like the right move.

After switching:
• OPFS alone didn’t help with the large collection, we still couldn’t insert everything.
• So we added sharding (10 shards, per the docs), and that allowed us to finally replicate the full data.

But then we ran into this memory issue:
• Now it affects most of the users, even those who had no problems before.
• We added key compression hoping to reduce memory load, but it either didn’t help or made things worse.
• Some collections couldn’t use compression because they include a "|v" field, which clashes with how compressed keys are prefixed. The error message was clear, but is there a workaround to make it work ?

The frustrating part is that the migration made things worse for users who were previously fine, and it still doesn’t fix things for the ones we were targeting.

We’re now testing a rollback to IndexedDB but now with sharding + key compression, this is the result of initial tests:
• On iPads where the app worked before, it still works fine.
• For the users we were targeting with this migration, some are now able to use the app, and the rest can use it with crashes from time to time, which in ideal.
• The app is noticeably slower compared to OPFS. (confirms what the docs say)

We’d love your input on whether this approach makes sense, and whether there’s anything else we could try to stabilize it further.

Thanks again!

@pubkey
Copy link
Owner

pubkey commented Apr 19, 2025

Can you reproduce the memory leak without dev-mode?
If it really is a memory-leak in the OPFS storage, let's find it together and I will fix that. This is the most likely case that would make it work for your users.

@morfees
Copy link
Author

morfees commented Apr 19, 2025

Can you reproduce the memory leak without dev-mode? If it really is a memory-leak in the OPFS storage, let's find it together and I will fix that. This is the most likely case that would make it work for your users.

When we test the app on an iPad (outside of dev mode), we can clearly see that it consumes significantly more RAM when using OPFS storage. Using tools like Device Monitor, RAM usage stays at around 98% consistently. It could be a memory leak, but it might also be that OPFS storage is just very memory-intensive. Debugging this is tricky though, as we only have access to the minified code and not the version with source maps.

@morfees
Copy link
Author

morfees commented Apr 19, 2025

Do you have any handy tools to track memory usage ?

@pubkey
Copy link
Owner

pubkey commented Apr 20, 2025

Do you have any handy tools to track memory usage ?

I only use chrome devtools with the memory profiler.

Can you post your schema? Or send it to me via discord if it contains private information.

The questions is if the memory is really leaking with OPFS or if you store have data that just has a high memory footprint because of how OPFS stores index-to-doc-mappings in memory.

@morfees
Copy link
Author

morfees commented Apr 23, 2025

@pubkey I have sent you the schema on discord.

@pubkey
Copy link
Owner

pubkey commented Apr 24, 2025

You schema has uid: { type: "string", maxLength: 100 } which means each in-memory index string will use 100*2byte for the primary key. Are your primary keys really that long? You can save memory by only having like maxLength: 32 for uuids.

Your schema does not have any indexes. This further indicates that there indeed is a memory-leak in OPFS storage itself.

@morfees
Copy link
Author

morfees commented Apr 24, 2025

The length will not exceed 20, we will change that.

Your schema does not have any indexes. This further indicates that there indeed is a memory-leak in OPFS storage itself.

We don't use indexes for this collection because we query all the data at once

Copy link

stale bot commented May 2, 2025

This issue has been automatically marked as stale because it has not had recent activity. It will be closed soon. Please update it or it may be closed to keep our repository organized. The best way is to add some more information or make a pull request with a test case. Also you might get help in fixing it at the RxDB Community Chat If you know you will continue working on this, just write any message to the issue (like "ping") to remove the stale tag.

@stale stale bot added the stale label May 2, 2025
@stale stale bot removed the stale label May 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants